{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Attack on the Auth, Replay Check\n",
    "- 1000 per case"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2025-03-05 11:14:16.437185: I tensorflow/tsl/cuda/cudart_stub.cc:28] Could not find cuda drivers on your machine, GPU will not be used.\n",
      "2025-03-05 11:14:16.499857: I tensorflow/tsl/cuda/cudart_stub.cc:28] Could not find cuda drivers on your machine, GPU will not be used.\n",
      "2025-03-05 11:14:16.500761: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.\n",
      "To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.\n",
      "2025-03-05 11:14:17.505506: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT\n"
     ]
    }
   ],
   "source": [
    "from tensorflow.keras.models import load_model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from datetime import datetime\n",
    "import random\n",
    "import zipfile"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from PIL import Image\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Imports and defs"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "def vertorizing_png_imges(address):\n",
    "  # Load the PNG image\n",
    "  image = Image.open(address)\n",
    "\n",
    "  # Convert the image to RGB mode\n",
    "  image = image.convert('RGB')\n",
    "\n",
    "  # Resize the image to match the input size expected by the CNN\n",
    "  desired_width = 31\n",
    "  desired_height = 20\n",
    "  image = image.resize((desired_width, desired_height))\n",
    "\n",
    "  # Convert the image to a NumPy array\n",
    "  image_array = np.array(image)\n",
    "\n",
    "  # Reshape the array to match the input shape expected by the CNN\n",
    "  # image_array = image_array.reshape((1, desired_height, desired_width, 3))\n",
    "\n",
    "  # Normalize the array\n",
    "  image_array = image_array.astype('float32') / 255.0\n",
    "\n",
    "  return image_array"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "from IPython.display import clear_output\n",
    "\n",
    "def progress_bar(index, total_length, name_of_list):\n",
    "    bar_length = 50\n",
    "\n",
    "    # Calculate the percentage of completion\n",
    "    percent_complete = (index / total_length) * 100\n",
    "\n",
    "    # Clear the current cell's output\n",
    "    clear_output(wait=True)\n",
    "\n",
    "    print(name_of_list)\n",
    "\n",
    "    # Print the progress bar\n",
    "    print(\"[\", end=\"\")\n",
    "    completed_blocks = int(bar_length * (percent_complete / 100))\n",
    "    print(\"*\" * completed_blocks, end=\"\")\n",
    "    print(\"-\" * (bar_length - completed_blocks), end=\"]\\n\")\n",
    "\n",
    "    # Print the progress in the format: index/total_length\n",
    "    print(f\"{index}/{total_length}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "def numerical_labels(labels_arr, dict_of_labels={}):\n",
    "  # This function change the labels of train and test\n",
    "  # data to numerical ones.\n",
    "  # Note: for the test data we should pass the train\n",
    "  # data labels\n",
    "\n",
    "  if dict_of_labels == {}:\n",
    "    unique_labels = np.unique(labels_arr)\n",
    "\n",
    "    for i, value in enumerate(unique_labels):\n",
    "        dict_of_labels[value] = i\n",
    "\n",
    "  # print(dict_of_labels)\n",
    "\n",
    "  num_lbls = []\n",
    "  for lbl in labels_arr:\n",
    "    num_lbls.append(dict_of_labels[lbl])\n",
    "\n",
    "  num_lbls = np.array(num_lbls)\n",
    "\n",
    "  return dict_of_labels, num_lbls"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "def false_acceptance_rate(y_true, y_pred):\n",
    "    \"\"\"\n",
    "    Computes the False Acceptance Rate (FAR).\n",
    "    \n",
    "    Args:\n",
    "        y_true (array-like): Ground-truth user IDs.\n",
    "        y_pred (array-like): Predicted user IDs.\n",
    "    \n",
    "    Returns:\n",
    "        float: False Acceptance Rate.\n",
    "    \"\"\"\n",
    "    false_accepts = np.sum((y_true != y_pred))  # Misclassified as another user\n",
    "    total_attempts = len(y_true)\n",
    "    return false_accepts / total_attempts\n",
    "\n",
    "def false_rejection_rate(y_true, y_pred):\n",
    "    \"\"\"\n",
    "    Computes the False Rejection Rate (FRR).\n",
    "    \n",
    "    Args:\n",
    "        y_true (array-like): Ground-truth user IDs.\n",
    "        y_pred (array-like): Predicted user IDs.\n",
    "    \n",
    "    Returns:\n",
    "        float: False Rejection Rate.\n",
    "    \"\"\"\n",
    "    false_rejections = np.sum((y_true == y_pred) == False)  # Misclassified cases\n",
    "    total_attempts = len(y_true)\n",
    "    return false_rejections / total_attempts\n",
    "\n",
    "def attack_success_rate(y_true, y_pred):\n",
    "    \"\"\"\n",
    "    Computes the overall Attack Success Rate (ASR).\n",
    "    \n",
    "    Args:\n",
    "        y_true (array-like): Ground-truth user IDs.\n",
    "        y_pred (array-like): Predicted user IDs.\n",
    "    \n",
    "    Returns:\n",
    "        float: Attack Success Rate.\n",
    "    \"\"\"\n",
    "    # Attack success = a sample is misclassified as another user (not itself)\n",
    "    successful_attacks = np.sum((y_true != y_pred))\n",
    "    total_attempts = len(y_true)\n",
    "    return successful_attacks / total_attempts\n",
    "\n",
    "def attack_success_rate_per_user(y_true, y_pred):\n",
    "    \"\"\"\n",
    "    Computes Attack Success Rate per user.\n",
    "    \n",
    "    Args:\n",
    "        y_true (array-like): Ground-truth user IDs.\n",
    "        y_pred (array-like): Predicted user IDs.\n",
    "    \n",
    "    Returns:\n",
    "        dict: Attack success rate for each user.\n",
    "    \"\"\"\n",
    "    unique_users = np.unique(y_true)\n",
    "    asr_per_user = {}\n",
    "\n",
    "    for user in unique_users:\n",
    "        user_mask = (y_true == user)  # Filter for this user's attempts\n",
    "        user_attempts = np.sum(user_mask)\n",
    "        user_successful_attacks = np.sum((y_true[user_mask] != y_pred[user_mask]))  # Misclassifications\n",
    "        \n",
    "        if user_attempts > 0:\n",
    "            asr_per_user[user] = user_successful_attacks / user_attempts\n",
    "        else:\n",
    "            asr_per_user[user] = 0.0  # If no attempts, ASR is 0\n",
    "\n",
    "    return asr_per_user"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "def creating_random_signal(len_signal):\n",
    "    random.rand()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from ishneholterlib import Holter\n",
    "import biosignalsnotebooks as bsnb\n",
    "from scipy.signal import detrend"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Getting users id\n",
    "users_id = []\n",
    "path = \"../users_EKM_files_6sec_5bpf\"\n",
    "dirs = os.listdir(path)\n",
    "for dir in dirs:\n",
    "  user_id = dir.split(\"_\")[-1]\n",
    "  users_id.append(user_id)\n",
    "\n",
    "dataset_path = \"../users_EKM_files_6sec_5bpf\"\n",
    "users_files = os.listdir(dataset_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "ecg200_dataset = \"/home/sadeghi/Amirhossein/ECG200\"\n",
    "ranges = {}\n",
    "for _user in users_id:\n",
    "    ranges[_user] = {}\n",
    "\n",
    "sum_x_max = 0\n",
    "sum_y_max = 0 \n",
    "sum_z_max = 0\n",
    "\n",
    "sum_x_min = 0\n",
    "sum_y_min = 0\n",
    "sum_z_min = 0\n",
    "\n",
    "for _file in os.listdir(ecg200_dataset):\n",
    "    if _file.endswith(\".ecg\"):\n",
    "        user = _file.split(\".\")[0]\n",
    "        ecg_file = _file\n",
    "        ecg_file_path = ecg200_dataset + \"/\" + ecg_file\n",
    "        user_leads_all_data = Holter(ecg_file_path)\n",
    "        user_leads_all_data.load_data()\n",
    "\n",
    "        x_lead = user_leads_all_data.lead[0].data\n",
    "        y_lead = user_leads_all_data.lead[1].data\n",
    "        z_lead = user_leads_all_data.lead[2].data\n",
    "\n",
    "        max_x_lead = max(x_lead) \n",
    "        max_y_lead = max(y_lead)\n",
    "        max_z_lead = max(z_lead)\n",
    "\n",
    "        min_x_lead = min(x_lead)\n",
    "        min_y_lead = min(y_lead)\n",
    "        min_z_lead = min(z_lead)\n",
    "\n",
    "        ranges[user][\"x_lead\"] = [max_x_lead, min_x_lead] \n",
    "        ranges[user][\"y_lead\"] = [max_y_lead, min_y_lead] \n",
    "        ranges[user][\"z_lead\"] = [max_z_lead, min_z_lead]\n",
    "\n",
    "        sum_x_max += max_x_lead\n",
    "        sum_y_max += max_y_lead \n",
    "        sum_z_max += max_z_lead\n",
    "    \n",
    "        sum_x_min += min_x_lead\n",
    "        sum_y_min += min_y_lead\n",
    "        sum_z_min += min_z_lead\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(f\"Average max x_lead: {max_x_lead / 199}\")\n",
    "print(f\"Average max y_lead: {max_y_lead / 199}\")\n",
    "print(f\"Average max z_lead: {max_z_lead / 199}\")\n",
    "print()\n",
    "print(f\"Average min x_lead{min_x_lead / 199}\")\n",
    "print(f\"Average min y_lead{min_y_lead / 199}\")\n",
    "print(f\"Average min z_lead{min_z_lead / 199}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Attack on: Omni_RI 5bpf, 6seconds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load the keras model\n",
    "omniRI_5bpf_6sec_model = load_model(\"./5bpf_6sec_inBoundary_1000_auth_6000_Omni_RI.keras\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Getting users id\n",
    "users_id = []\n",
    "path = \"../users_EKM_files_6sec_5bpf\"\n",
    "dirs = os.listdir(path)\n",
    "for dir in dirs:\n",
    "  user_id = dir.split(\"_\")[-1]\n",
    "  users_id.append(user_id)\n",
    "\n",
    "dataset_path = \"../users_EKM_files_6sec_5bpf\"\n",
    "users_files = os.listdir(dataset_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Selecting N amount of EKMs for each user\n",
    "users_bpf_EKMs_x = []\n",
    "users_bpf_EKMs_y = []\n",
    "\n",
    "N_each_user_ekms_amount = 400\n",
    "dataset_path = \"../users_EKM_files_6sec_5bpf\"\n",
    "\n",
    "for _files in users_files:\n",
    "    user_id = _files.split(\"_\")[-1]\n",
    "    if user_id in users_id:\n",
    "      for _ekm_number in range(N_each_user_ekms_amount):\n",
    "        # 5bpf-ekm-bpf_recording_signal_length_ekm_dataset-2005-1008.png\n",
    "        users_bpf_EKMs_x.append(f\"{dataset_path}/{user_id}/y_lead/5bpf-ekm-bpf_recording_signal_length_ekm_dataset-{user_id}-{_ekm_number}.png\")\n",
    "        users_bpf_EKMs_y.append(user_id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Vectorizing EKMs of users\n",
    "for index, ekm_path in enumerate(users_bpf_EKMs_x):\n",
    "  # progress_bar(index, len(users_bpf_EKMs_x), \"Vertorizing\")\n",
    "  users_bpf_EKMs_x[index] = vertorizing_png_imges(ekm_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {},
   "outputs": [],
   "source": [
    "label_dict, users_bpf_EKMs_y = numerical_labels(users_bpf_EKMs_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [],
   "source": [
    "users_bpf_EKMs_x = np.array(users_bpf_EKMs_x)\n",
    "users_bpf_EKMs_y = np.array(users_bpf_EKMs_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2488/2488 [==============================] - 18s 7ms/step\n"
     ]
    }
   ],
   "source": [
    "y_prob = omniRI_5bpf_6sec_model.predict(users_bpf_EKMs_x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Calculating attack measurements (ASR: Attack Success Rate)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 127,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Attack Success Rate (ASR): 1.2462%\n",
      "\n",
      "Attack Success Rate per User:\n",
      "User 0: 1.0000%\n",
      "User 1: 4.0000%\n",
      "User 2: 0.2500%\n",
      "User 3: 0.5000%\n",
      "User 4: 1.2500%\n",
      "User 5: 0.0000%\n",
      "User 6: 0.2500%\n",
      "User 7: 0.5000%\n",
      "User 8: 1.0000%\n",
      "User 9: 3.0000%\n",
      "User 10: 8.0000%\n",
      "User 11: 0.0000%\n",
      "User 12: 0.5000%\n",
      "User 13: 1.7500%\n",
      "User 14: 6.2500%\n",
      "User 15: 1.0000%\n",
      "User 16: 3.0000%\n",
      "User 17: 1.0000%\n",
      "User 18: 0.2500%\n",
      "User 19: 0.0000%\n",
      "User 20: 0.7500%\n",
      "User 21: 1.5000%\n",
      "User 22: 4.2500%\n",
      "User 23: 2.2500%\n",
      "User 24: 1.0000%\n",
      "User 25: 0.0000%\n",
      "User 26: 0.7500%\n",
      "User 27: 0.2500%\n",
      "User 28: 0.0000%\n",
      "User 29: 0.0000%\n",
      "User 30: 0.0000%\n",
      "User 31: 0.0000%\n",
      "User 32: 0.2500%\n",
      "User 33: 0.0000%\n",
      "User 34: 0.2500%\n",
      "User 35: 1.7500%\n",
      "User 36: 0.2500%\n",
      "User 37: 1.7500%\n",
      "User 38: 0.7500%\n",
      "User 39: 4.5000%\n",
      "User 40: 0.0000%\n",
      "User 41: 0.0000%\n",
      "User 42: 0.2500%\n",
      "User 43: 0.2500%\n",
      "User 44: 0.2500%\n",
      "User 45: 9.7500%\n",
      "User 46: 0.0000%\n",
      "User 47: 1.2500%\n",
      "User 48: 0.7500%\n",
      "User 49: 0.0000%\n",
      "User 50: 0.5000%\n",
      "User 51: 1.7500%\n",
      "User 52: 2.2500%\n",
      "User 53: 7.0000%\n",
      "User 54: 0.2500%\n",
      "User 55: 3.5000%\n",
      "User 56: 0.0000%\n",
      "User 57: 0.0000%\n",
      "User 58: 0.0000%\n",
      "User 59: 0.0000%\n",
      "User 60: 0.0000%\n",
      "User 61: 0.0000%\n",
      "User 62: 0.7500%\n",
      "User 63: 0.5000%\n",
      "User 64: 0.5000%\n",
      "User 65: 1.2500%\n",
      "User 66: 2.2500%\n",
      "User 67: 1.2500%\n",
      "User 68: 0.7500%\n",
      "User 69: 1.0000%\n",
      "User 70: 0.2500%\n",
      "User 71: 0.0000%\n",
      "User 72: 0.5000%\n",
      "User 73: 0.2500%\n",
      "User 74: 1.5000%\n",
      "User 75: 0.5000%\n",
      "User 76: 0.2500%\n",
      "User 77: 0.7500%\n",
      "User 78: 0.0000%\n",
      "User 79: 0.5000%\n",
      "User 80: 1.2500%\n",
      "User 81: 0.0000%\n",
      "User 82: 0.5000%\n",
      "User 83: 0.0000%\n",
      "User 84: 3.0000%\n",
      "User 85: 0.0000%\n",
      "User 86: 0.0000%\n",
      "User 87: 0.2500%\n",
      "User 88: 2.5000%\n",
      "User 89: 3.0000%\n",
      "User 90: 0.5000%\n",
      "User 91: 4.7500%\n",
      "User 92: 2.0000%\n",
      "User 93: 0.2500%\n",
      "User 94: 0.2500%\n",
      "User 95: 2.2500%\n",
      "User 96: 0.0000%\n",
      "User 97: 7.7500%\n",
      "User 98: 4.2500%\n",
      "User 99: 1.2500%\n",
      "User 100: 3.0000%\n",
      "User 101: 7.5000%\n",
      "User 102: 0.7500%\n",
      "User 103: 0.0000%\n",
      "User 104: 0.0000%\n",
      "User 105: 0.5000%\n",
      "User 106: 0.0000%\n",
      "User 107: 1.7500%\n",
      "User 108: 0.0000%\n",
      "User 109: 7.0000%\n",
      "User 110: 1.2500%\n",
      "User 111: 1.7500%\n",
      "User 112: 0.0000%\n",
      "User 113: 0.7500%\n",
      "User 114: 2.7500%\n",
      "User 115: 0.0000%\n",
      "User 116: 3.2500%\n",
      "User 117: 0.5000%\n",
      "User 118: 0.5000%\n",
      "User 119: 1.0000%\n",
      "User 120: 4.7500%\n",
      "User 121: 2.2500%\n",
      "User 122: 1.2500%\n",
      "User 123: 5.2500%\n",
      "User 124: 0.2500%\n",
      "User 125: 3.0000%\n",
      "User 126: 0.2500%\n",
      "User 127: 1.5000%\n",
      "User 128: 1.7500%\n",
      "User 129: 4.0000%\n",
      "User 130: 4.2500%\n",
      "User 131: 0.0000%\n",
      "User 132: 0.0000%\n",
      "User 133: 2.2500%\n",
      "User 134: 0.5000%\n",
      "User 135: 1.7500%\n",
      "User 136: 0.2500%\n",
      "User 137: 1.0000%\n",
      "User 138: 4.0000%\n",
      "User 139: 0.0000%\n",
      "User 140: 0.0000%\n",
      "User 141: 2.2500%\n",
      "User 142: 3.0000%\n",
      "User 143: 1.5000%\n",
      "User 144: 0.0000%\n",
      "User 145: 0.0000%\n",
      "User 146: 2.7500%\n",
      "User 147: 0.0000%\n",
      "User 148: 0.7500%\n",
      "User 149: 0.2500%\n",
      "User 150: 1.5000%\n",
      "User 151: 0.0000%\n",
      "User 152: 2.0000%\n",
      "User 153: 0.2500%\n",
      "User 154: 1.0000%\n",
      "User 155: 0.5000%\n",
      "User 156: 0.5000%\n",
      "User 157: 0.0000%\n",
      "User 158: 1.2500%\n",
      "User 159: 1.0000%\n",
      "User 160: 0.7500%\n",
      "User 161: 4.2500%\n",
      "User 162: 0.0000%\n",
      "User 163: 2.2500%\n",
      "User 164: 0.7500%\n",
      "User 165: 0.2500%\n",
      "User 166: 0.5000%\n",
      "User 167: 0.7500%\n",
      "User 168: 0.2500%\n",
      "User 169: 0.0000%\n",
      "User 170: 2.2500%\n",
      "User 171: 0.5000%\n",
      "User 172: 0.2500%\n",
      "User 173: 0.2500%\n",
      "User 174: 0.0000%\n",
      "User 175: 0.0000%\n",
      "User 176: 0.0000%\n",
      "User 177: 0.2500%\n",
      "User 178: 0.0000%\n",
      "User 179: 2.0000%\n",
      "User 180: 3.5000%\n",
      "User 181: 0.0000%\n",
      "User 182: 0.2500%\n",
      "User 183: 0.0000%\n",
      "User 184: 2.2500%\n",
      "User 185: 0.0000%\n",
      "User 186: 0.0000%\n",
      "User 187: 0.2500%\n",
      "User 188: 0.0000%\n",
      "User 189: 0.0000%\n",
      "User 190: 1.5000%\n",
      "User 191: 0.5000%\n",
      "User 192: 0.2500%\n",
      "User 193: 0.0000%\n",
      "User 194: 0.2500%\n",
      "User 195: 2.2500%\n",
      "User 196: 3.7500%\n",
      "User 197: 0.0000%\n",
      "User 198: 1.0000%\n"
     ]
    }
   ],
   "source": [
    "# far = false_acceptance_rate(users_bpf_EKMs_y, y_prob.argmax(axis=1))  # Assuming softmax output\n",
    "# frr = false_rejection_rate(users_bpf_EKMs_y, y_prob.argmax(axis=1))\n",
    "asr = attack_success_rate(users_bpf_EKMs_y, y_prob.argmax(axis=1))\n",
    "asr_per_user = attack_success_rate_per_user(users_bpf_EKMs_y, y_prob.argmax(axis=1))\n",
    "\n",
    "# Print results\n",
    "# print(f\"False Acceptance Rate (FAR): {far:.6f}\")\n",
    "# print(f\"False Rejection Rate (FRR): {frr:.6f}\")\n",
    "print(f\"Attack Success Rate (ASR): {asr*100:.4f}%\")\n",
    "\n",
    "print(\"\\nAttack Success Rate per User:\")\n",
    "max = 0\n",
    "max_id = \"\"\n",
    "min = 100\n",
    "min_id = \"\"\n",
    "\n",
    "for user, rate in asr_per_user.items():\n",
    "    if max < rate:\n",
    "        max = rate\n",
    "        max_id = user\n",
    "    if min > rate:\n",
    "        min = rate\n",
    "        min_id = user\n",
    "    print(f\"User {user}: {rate*100:.4f}%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Max success attack: user 45: 9.75%\n",
      "Min success attack: user 5: 0.0%\n"
     ]
    }
   ],
   "source": [
    "print(f\"Max success attack: user {max_id}: {max*100}%\")\n",
    "print(f\"Min success attack: user {min_id}: {min*100}%\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Attack on: Mono_RI 5bpf, 6seconds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load the keras model\n",
    "monoRI_5bpf_6sec_model = load_model(\"./5bpf_6sec_inBoundary_1000_auth_6000_Mono_RI_user1027.keras\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Getting users id\n",
    "users_id = []\n",
    "path = \"../users_EKM_files_6sec_5bpf\"\n",
    "dirs = os.listdir(path)\n",
    "for dir in dirs:\n",
    "  user_id = dir.split(\"_\")[-1]\n",
    "  users_id.append(user_id)\n",
    "\n",
    "dataset_path = \"../users_EKM_files_6sec_5bpf\"\n",
    "users_files = os.listdir(dataset_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 131,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Creating dict of counters for each randomly-chosen users\n",
    "# of ecg 200 dataset\n",
    "# Also creating dict of users' EKMs\n",
    "ecg_200_users_EKM_amount_dict = {}\n",
    "ecg_200_users_EKMs_dict = {}\n",
    "\n",
    "for user in users_id:\n",
    "  ecg_200_users_EKM_amount_dict[user] = 0\n",
    "  ecg_200_users_EKMs_dict[user] = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Counting each user's EKMs in dataset and collecting EKMs of him/her\n",
    "dataset_path = \"../users_EKM_files_6sec_5bpf\"\n",
    "users_files = os.listdir(dataset_path)\n",
    "\n",
    "for _files in users_files:\n",
    "    user_id = _files.split(\"_\")[-1]\n",
    "    if user_id in users_id:\n",
    "      ecg_200_users_EKM_amount_dict[user_id] = len(os.listdir(f\"{dataset_path}/{user_id}/y_lead\"))\n",
    "      ecg_200_users_EKMs_dict[user_id] = os.listdir(f\"{dataset_path}/{user_id}/y_lead\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 133,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Function to extract the number at the end of the string\n",
    "import re\n",
    "def extract_number(s): \n",
    "  match = re.search(r'-(\\d+)\\.png$', s) \n",
    "  return int(match.group(1)) if match else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 134,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset_path = \"../users_EKM_files_6sec_5bpf\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 135,
   "metadata": {},
   "outputs": [],
   "source": [
    "def one_vs_all_EKMs(user_id):\n",
    "    '''\n",
    "    Gets the id of user and returns the X and y for the model\n",
    "    '''\n",
    "\n",
    "    # Selecting N amount of EKMs for the random user\n",
    "    users_bpf_EKMs_x = []\n",
    "    users_bpf_EKMs_y = []\n",
    "\n",
    "    N_each_user_ekms_amount = 400\n",
    "\n",
    "    if user_id in users_id:\n",
    "        userid_ekms = ecg_200_users_EKMs_dict[user_id][:N_each_user_ekms_amount]\n",
    "        \n",
    "        # Sort the array based on the extracted number \n",
    "        sorted_userid_ekms = sorted(userid_ekms, key=extract_number)\n",
    "        \n",
    "        if len(sorted_userid_ekms) < N_each_user_ekms_amount:\n",
    "            print(user_id, len(sorted_userid_ekms))\n",
    "        \n",
    "        for _ekm in sorted_userid_ekms:\n",
    "            # 5bpf-ekm-bpf_recording_signal_length_ekm_dataset-2005-1008.png\n",
    "            users_bpf_EKMs_x.append(f\"{dataset_path}/{user_id}/y_lead/{_ekm}\")\n",
    "            users_bpf_EKMs_y.append(1)\n",
    "\n",
    "    # Selecting N amount of EKMs for the rest of users\n",
    "    rest_users = [_ for _ in users_files if _ != user_id]\n",
    "    N_rest_user_ekms_amount = 8  # 400 / 199 => 2\n",
    "\n",
    "    for _files in rest_users[:50]:\n",
    "        rest_user_id = _files.split(\"_\")[-1]\n",
    "        if rest_user_id in users_id:\n",
    "            userid_ekms = ecg_200_users_EKMs_dict[rest_user_id][:N_rest_user_ekms_amount]\n",
    "            # Sort the array based on the extracted number \n",
    "            sorted_userid_ekms = sorted(userid_ekms, key=extract_number)\n",
    "            \n",
    "            if len(sorted_userid_ekms) < N_rest_user_ekms_amount:\n",
    "                print(rest_user_id, len(sorted_userid_ekms))\n",
    "            \n",
    "            for _ekm in sorted_userid_ekms:\n",
    "                # 5bpf-ekm-bpf_recording_signal_length_ekm_dataset-2005-1008.png\n",
    "                users_bpf_EKMs_x.append(f\"{dataset_path}/{rest_user_id}/y_lead/{_ekm}\")\n",
    "                users_bpf_EKMs_y.append(0)\n",
    "    \n",
    "    return users_bpf_EKMs_x, users_bpf_EKMs_y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 136,
   "metadata": {},
   "outputs": [],
   "source": [
    "users_bpf_EKMs_x, users_bpf_EKMs_y = one_vs_all_EKMs(\"1027\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 137,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Vectorizing EKMs of users\n",
    "for index, ekm_path in enumerate(users_bpf_EKMs_x):\n",
    "  # progress_bar(index, len(users_bpf_EKMs_x), \"Vertorizing\")\n",
    "  users_bpf_EKMs_x[index] = vertorizing_png_imges(ekm_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 138,
   "metadata": {},
   "outputs": [],
   "source": [
    "users_bpf_EKMs_x = np.array(users_bpf_EKMs_x)\n",
    "users_bpf_EKMs_y = np.array(users_bpf_EKMs_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 139,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "25/25 [==============================] - 0s 7ms/step\n"
     ]
    }
   ],
   "source": [
    "y_prob = monoRI_5bpf_6sec_model.predict(users_bpf_EKMs_x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 140,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Attack Success Rate (ASR): 0.3750%\n",
      "\n",
      "Attack Success Rate per User:\n",
      "User 0: 0.5000%\n",
      "User 1: 0.2500%\n"
     ]
    }
   ],
   "source": [
    "asr = attack_success_rate(users_bpf_EKMs_y, y_prob.argmax(axis=1))\n",
    "asr_per_user = attack_success_rate_per_user(users_bpf_EKMs_y, y_prob.argmax(axis=1))\n",
    "\n",
    "# Print results\n",
    "print(f\"Attack Success Rate (ASR): {asr*100:.4f}%\")\n",
    "\n",
    "print(\"\\nAttack Success Rate per User:\")\n",
    "max = 0\n",
    "max_id = \"\"\n",
    "min = 100\n",
    "min_id = \"\"\n",
    "\n",
    "for user, rate in asr_per_user.items():\n",
    "    if max < rate:\n",
    "        max = rate\n",
    "        max_id = user\n",
    "    if min > rate:\n",
    "        min = rate\n",
    "        min_id = user\n",
    "    print(f\"User {user}: {rate*100:.4f}%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 143,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Max success attack: user 0: 0.5%\n",
      "Min success attack: user 1: 0.25%\n"
     ]
    }
   ],
   "source": [
    "print(f\"Max success attack: user {max_id}: {max*100}%\")\n",
    "print(f\"Min success attack: user {min_id}: {min*100}%\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Attack on: Omni_RI 5bpf, 5seconds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 144,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load the keras model\n",
    "omniRI_5bpf_5sec_model = load_model(\"./5bpf_5sec_inBoundary_1000_auth_6000_Omni_RI.keras\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 145,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Getting users id\n",
    "users_id = []\n",
    "path = \"../users_EKM_files_5sec_5bpf\"\n",
    "dirs = os.listdir(path)\n",
    "for dir in dirs:\n",
    "  user_id = dir.split(\"_\")[-1]\n",
    "  users_id.append(user_id)\n",
    "\n",
    "dataset_path = \"../users_EKM_files_5sec_5bpf\"\n",
    "users_files = os.listdir(dataset_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 146,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Selecting N amount of EKMs for each user\n",
    "users_bpf_EKMs_x = []\n",
    "users_bpf_EKMs_y = []\n",
    "\n",
    "N_each_user_ekms_amount = 400\n",
    "dataset_path = \"../users_EKM_files_5sec_5bpf\"\n",
    "\n",
    "for _files in users_files:\n",
    "    user_id = _files.split(\"_\")[-1]\n",
    "    if user_id in users_id:\n",
    "      for _ekm_number in range(N_each_user_ekms_amount):\n",
    "        # 5bpf-ekm-bpf_recording_signal_length_ekm_dataset-2005-1008.png\n",
    "        users_bpf_EKMs_x.append(f\"{dataset_path}/{user_id}/y_lead/5bpf-ekm-bpf_recording_signal_length_ekm_dataset-{user_id}-{_ekm_number}.png\")\n",
    "        users_bpf_EKMs_y.append(user_id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 147,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Vectorizing EKMs of users\n",
    "for index, ekm_path in enumerate(users_bpf_EKMs_x):\n",
    "  # progress_bar(index, len(users_bpf_EKMs_x), \"Vertorizing\")\n",
    "  users_bpf_EKMs_x[index] = vertorizing_png_imges(ekm_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 148,
   "metadata": {},
   "outputs": [],
   "source": [
    "label_dict, users_bpf_EKMs_y = numerical_labels(users_bpf_EKMs_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 149,
   "metadata": {},
   "outputs": [],
   "source": [
    "users_bpf_EKMs_x = np.array(users_bpf_EKMs_x)\n",
    "users_bpf_EKMs_y = np.array(users_bpf_EKMs_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 150,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2488/2488 [==============================] - 18s 7ms/step\n"
     ]
    }
   ],
   "source": [
    "y_prob = omniRI_5bpf_5sec_model.predict(users_bpf_EKMs_x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Attack Success Rate (ASR): 5.4862%\n",
      "\n",
      "Attack Success Rate per User:\n",
      "User 0: 3.0000%\n",
      "User 1: 19.0000%\n",
      "User 2: 1.0000%\n",
      "User 3: 4.0000%\n",
      "User 4: 0.5000%\n",
      "User 5: 0.7500%\n",
      "User 6: 0.5000%\n",
      "User 7: 0.7500%\n",
      "User 8: 9.5000%\n",
      "User 9: 9.2500%\n",
      "User 10: 15.5000%\n",
      "User 11: 3.7500%\n",
      "User 12: 4.5000%\n",
      "User 13: 13.5000%\n",
      "User 14: 14.7500%\n",
      "User 15: 4.2500%\n",
      "User 16: 4.0000%\n",
      "User 17: 1.2500%\n",
      "User 18: 1.5000%\n",
      "User 19: 0.2500%\n",
      "User 20: 2.0000%\n",
      "User 21: 3.2500%\n",
      "User 22: 18.5000%\n",
      "User 23: 7.0000%\n",
      "User 24: 2.2500%\n",
      "User 25: 0.2500%\n",
      "User 26: 3.2500%\n",
      "User 27: 0.5000%\n",
      "User 28: 0.5000%\n",
      "User 29: 4.0000%\n",
      "User 30: 2.5000%\n",
      "User 31: 1.7500%\n",
      "User 32: 6.2500%\n",
      "User 33: 0.2500%\n",
      "User 34: 2.2500%\n",
      "User 35: 6.7500%\n",
      "User 36: 2.0000%\n",
      "User 37: 1.2500%\n",
      "User 38: 1.2500%\n",
      "User 39: 16.7500%\n",
      "User 40: 0.0000%\n",
      "User 41: 1.0000%\n",
      "User 42: 1.2500%\n",
      "User 43: 0.7500%\n",
      "User 44: 0.2500%\n",
      "User 45: 22.0000%\n",
      "User 46: 0.0000%\n",
      "User 47: 0.7500%\n",
      "User 48: 3.2500%\n",
      "User 49: 0.2500%\n",
      "User 50: 4.7500%\n",
      "User 51: 7.0000%\n",
      "User 52: 23.0000%\n",
      "User 53: 26.0000%\n",
      "User 54: 0.5000%\n",
      "User 55: 14.0000%\n",
      "User 56: 0.0000%\n",
      "User 57: 1.0000%\n",
      "User 58: 3.0000%\n",
      "User 59: 0.2500%\n",
      "User 60: 2.2500%\n",
      "User 61: 4.2500%\n",
      "User 62: 1.0000%\n",
      "User 63: 1.2500%\n",
      "User 64: 4.7500%\n",
      "User 65: 7.5000%\n",
      "User 66: 14.5000%\n",
      "User 67: 5.7500%\n",
      "User 68: 6.5000%\n",
      "User 69: 2.7500%\n",
      "User 70: 0.2500%\n",
      "User 71: 0.2500%\n",
      "User 72: 4.2500%\n",
      "User 73: 2.7500%\n",
      "User 74: 3.0000%\n",
      "User 75: 1.7500%\n",
      "User 76: 2.5000%\n",
      "User 77: 0.7500%\n",
      "User 78: 0.0000%\n",
      "User 79: 0.2500%\n",
      "User 80: 9.0000%\n",
      "User 81: 1.2500%\n",
      "User 82: 1.2500%\n",
      "User 83: 1.2500%\n",
      "User 84: 29.5000%\n",
      "User 85: 6.0000%\n",
      "User 86: 5.0000%\n",
      "User 87: 1.2500%\n",
      "User 88: 5.0000%\n",
      "User 89: 15.2500%\n",
      "User 90: 4.7500%\n",
      "User 91: 24.2500%\n",
      "User 92: 8.0000%\n",
      "User 93: 5.7500%\n",
      "User 94: 3.7500%\n",
      "User 95: 18.2500%\n",
      "User 96: 3.2500%\n",
      "User 97: 53.0000%\n",
      "User 98: 13.2500%\n",
      "User 99: 2.5000%\n",
      "User 100: 23.2500%\n",
      "User 101: 10.0000%\n",
      "User 102: 1.5000%\n",
      "User 103: 0.2500%\n",
      "User 104: 6.0000%\n",
      "User 105: 4.5000%\n",
      "User 106: 1.0000%\n",
      "User 107: 19.7500%\n",
      "User 108: 2.0000%\n",
      "User 109: 7.0000%\n",
      "User 110: 10.7500%\n",
      "User 111: 13.2500%\n",
      "User 112: 4.2500%\n",
      "User 113: 6.0000%\n",
      "User 114: 1.0000%\n",
      "User 115: 0.7500%\n",
      "User 116: 3.0000%\n",
      "User 117: 3.0000%\n",
      "User 118: 0.0000%\n",
      "User 119: 15.5000%\n",
      "User 120: 6.0000%\n",
      "User 121: 10.5000%\n",
      "User 122: 3.5000%\n",
      "User 123: 14.7500%\n",
      "User 124: 0.5000%\n",
      "User 125: 5.7500%\n",
      "User 126: 6.2500%\n",
      "User 127: 4.5000%\n",
      "User 128: 7.7500%\n",
      "User 129: 11.7500%\n",
      "User 130: 19.5000%\n",
      "User 131: 0.2500%\n",
      "User 132: 0.0000%\n",
      "User 133: 4.2500%\n",
      "User 134: 19.0000%\n",
      "User 135: 2.5000%\n",
      "User 136: 0.2500%\n",
      "User 137: 1.2500%\n",
      "User 138: 13.5000%\n",
      "User 139: 5.7500%\n",
      "User 140: 2.5000%\n",
      "User 141: 17.5000%\n",
      "User 142: 6.0000%\n",
      "User 143: 16.7500%\n",
      "User 144: 0.7500%\n",
      "User 145: 0.2500%\n",
      "User 146: 14.5000%\n",
      "User 147: 11.0000%\n",
      "User 148: 4.0000%\n",
      "User 149: 0.0000%\n",
      "User 150: 15.5000%\n",
      "User 151: 0.5000%\n",
      "User 152: 0.2500%\n",
      "User 153: 6.7500%\n",
      "User 154: 2.5000%\n",
      "User 155: 5.0000%\n",
      "User 156: 3.5000%\n",
      "User 157: 4.0000%\n",
      "User 158: 2.7500%\n",
      "User 159: 2.2500%\n",
      "User 160: 4.7500%\n",
      "User 161: 20.2500%\n",
      "User 162: 0.2500%\n",
      "User 163: 7.0000%\n",
      "User 164: 2.5000%\n",
      "User 165: 1.0000%\n",
      "User 166: 1.2500%\n",
      "User 167: 0.5000%\n",
      "User 168: 0.0000%\n",
      "User 169: 0.2500%\n",
      "User 170: 8.2500%\n",
      "User 171: 1.0000%\n",
      "User 172: 0.7500%\n",
      "User 173: 0.7500%\n",
      "User 174: 0.0000%\n",
      "User 175: 4.7500%\n",
      "User 176: 1.0000%\n",
      "User 177: 0.2500%\n",
      "User 178: 0.5000%\n",
      "User 179: 1.7500%\n",
      "User 180: 19.0000%\n",
      "User 181: 1.0000%\n",
      "User 182: 0.0000%\n",
      "User 183: 1.5000%\n",
      "User 184: 7.5000%\n",
      "User 185: 3.2500%\n",
      "User 186: 1.0000%\n",
      "User 187: 0.2500%\n",
      "User 188: 2.2500%\n",
      "User 189: 2.0000%\n",
      "User 190: 1.0000%\n",
      "User 191: 3.0000%\n",
      "User 192: 1.2500%\n",
      "User 193: 0.0000%\n",
      "User 194: 3.0000%\n",
      "User 195: 1.7500%\n",
      "User 196: 18.7500%\n",
      "User 197: 0.2500%\n",
      "User 198: 1.0000%\n"
     ]
    }
   ],
   "source": [
    "asr = attack_success_rate(users_bpf_EKMs_y, y_prob.argmax(axis=1))\n",
    "asr_per_user = attack_success_rate_per_user(users_bpf_EKMs_y, y_prob.argmax(axis=1))\n",
    "\n",
    "# Print results\n",
    "print(f\"Attack Success Rate (ASR): {asr*100:.4f}%\")\n",
    "\n",
    "print(\"\\nAttack Success Rate per User:\")\n",
    "max = 0\n",
    "max_id = \"\"\n",
    "min = 100\n",
    "min_id = \"\"\n",
    "\n",
    "for user, rate in asr_per_user.items():\n",
    "    if max < rate:\n",
    "        max = rate\n",
    "        max_id = user\n",
    "    if min > rate:\n",
    "        min = rate\n",
    "        min_id = user\n",
    "    print(f\"User {user}: {rate*100:.4f}%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 152,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Max success attack: user 97: 53.0%\n",
      "Min success attack: user 40: 0.0%\n"
     ]
    }
   ],
   "source": [
    "print(f\"Max success attack: user {max_id}: {max*100}%\")\n",
    "print(f\"Min success attack: user {min_id}: {min*100}%\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Attack on: Mono_RI 5bpf, 7seconds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 153,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load the keras model\n",
    "monoRI_5bpf_7sec_model = load_model(\"./5bpf_7sec_inBoundary_1000_auth_6000_Mono_RI_user1027.keras\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 154,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Getting users id\n",
    "users_id = []\n",
    "path = \"../users_EKM_files_7sec_5bpf\"\n",
    "dirs = os.listdir(path)\n",
    "for dir in dirs:\n",
    "  user_id = dir.split(\"_\")[-1]\n",
    "  users_id.append(user_id)\n",
    "\n",
    "dataset_path = \"../users_EKM_files_7sec_5bpf\"\n",
    "users_files = os.listdir(dataset_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 155,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Creating dict of counters for each randomly-chosen users\n",
    "# of ecg 200 dataset\n",
    "# Also creating dict of users' EKMs\n",
    "ecg_200_users_EKM_amount_dict = {}\n",
    "ecg_200_users_EKMs_dict = {}\n",
    "\n",
    "for user in users_id:\n",
    "  ecg_200_users_EKM_amount_dict[user] = 0\n",
    "  ecg_200_users_EKMs_dict[user] = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 156,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Counting each user's EKMs in dataset and collecting EKMs of him/her\n",
    "dataset_path = \"../users_EKM_files_7sec_5bpf\"\n",
    "users_files = os.listdir(dataset_path)\n",
    "\n",
    "for _files in users_files:\n",
    "    user_id = _files.split(\"_\")[-1]\n",
    "    if user_id in users_id:\n",
    "      ecg_200_users_EKM_amount_dict[user_id] = len(os.listdir(f\"{dataset_path}/{user_id}/y_lead\"))\n",
    "      ecg_200_users_EKMs_dict[user_id] = os.listdir(f\"{dataset_path}/{user_id}/y_lead\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 157,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Function to extract the number at the end of the string\n",
    "import re\n",
    "def extract_number(s): \n",
    "  match = re.search(r'-(\\d+)\\.png$', s) \n",
    "  return int(match.group(1)) if match else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 158,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset_path = \"../users_EKM_files_7sec_5bpf\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 159,
   "metadata": {},
   "outputs": [],
   "source": [
    "def one_vs_all_EKMs(user_id):\n",
    "    '''\n",
    "    Gets the id of user and returns the X and y for the model\n",
    "    '''\n",
    "\n",
    "    # Selecting N amount of EKMs for the random user\n",
    "    users_bpf_EKMs_x = []\n",
    "    users_bpf_EKMs_y = []\n",
    "\n",
    "    N_each_user_ekms_amount = 400\n",
    "\n",
    "    if user_id in users_id:\n",
    "        userid_ekms = ecg_200_users_EKMs_dict[user_id][:N_each_user_ekms_amount]\n",
    "        \n",
    "        # Sort the array based on the extracted number \n",
    "        sorted_userid_ekms = sorted(userid_ekms, key=extract_number)\n",
    "        \n",
    "        if len(sorted_userid_ekms) < N_each_user_ekms_amount:\n",
    "            print(user_id, len(sorted_userid_ekms))\n",
    "        \n",
    "        for _ekm in sorted_userid_ekms:\n",
    "            # 5bpf-ekm-bpf_recording_signal_length_ekm_dataset-2005-1008.png\n",
    "            users_bpf_EKMs_x.append(f\"{dataset_path}/{user_id}/y_lead/{_ekm}\")\n",
    "            users_bpf_EKMs_y.append(1)\n",
    "\n",
    "    # Selecting N amount of EKMs for the rest of users\n",
    "    rest_users = [_ for _ in users_files if _ != user_id]\n",
    "    N_rest_user_ekms_amount = 8  # 400 / 199 => 2\n",
    "\n",
    "    for _files in rest_users[:50]:\n",
    "        rest_user_id = _files.split(\"_\")[-1]\n",
    "        if rest_user_id in users_id:\n",
    "            userid_ekms = ecg_200_users_EKMs_dict[rest_user_id][:N_rest_user_ekms_amount]\n",
    "            # Sort the array based on the extracted number \n",
    "            sorted_userid_ekms = sorted(userid_ekms, key=extract_number)\n",
    "            \n",
    "            if len(sorted_userid_ekms) < N_rest_user_ekms_amount:\n",
    "                print(rest_user_id, len(sorted_userid_ekms))\n",
    "            \n",
    "            for _ekm in sorted_userid_ekms:\n",
    "                # 5bpf-ekm-bpf_recording_signal_length_ekm_dataset-2005-1008.png\n",
    "                users_bpf_EKMs_x.append(f\"{dataset_path}/{rest_user_id}/y_lead/{_ekm}\")\n",
    "                users_bpf_EKMs_y.append(0)\n",
    "    \n",
    "    return users_bpf_EKMs_x, users_bpf_EKMs_y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 160,
   "metadata": {},
   "outputs": [],
   "source": [
    "users_bpf_EKMs_x, users_bpf_EKMs_y = one_vs_all_EKMs(\"1027\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 162,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Vectorizing EKMs of users\n",
    "for index, ekm_path in enumerate(users_bpf_EKMs_x):\n",
    "  # progress_bar(index, len(users_bpf_EKMs_x), \"Vertorizing\")\n",
    "  users_bpf_EKMs_x[index] = vertorizing_png_imges(ekm_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 163,
   "metadata": {},
   "outputs": [],
   "source": [
    "users_bpf_EKMs_x = np.array(users_bpf_EKMs_x)\n",
    "users_bpf_EKMs_y = np.array(users_bpf_EKMs_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 164,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "25/25 [==============================] - 0s 8ms/step\n"
     ]
    }
   ],
   "source": [
    "y_prob = monoRI_5bpf_6sec_model.predict(users_bpf_EKMs_x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 165,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Attack Success Rate (ASR): 2.6250%\n",
      "\n",
      "Attack Success Rate per User:\n",
      "User 0: 2.5000%\n",
      "User 1: 2.7500%\n"
     ]
    }
   ],
   "source": [
    "asr = attack_success_rate(users_bpf_EKMs_y, y_prob.argmax(axis=1))\n",
    "asr_per_user = attack_success_rate_per_user(users_bpf_EKMs_y, y_prob.argmax(axis=1))\n",
    "\n",
    "# Print results\n",
    "print(f\"Attack Success Rate (ASR): {asr*100:.4f}%\")\n",
    "\n",
    "print(\"\\nAttack Success Rate per User:\")\n",
    "max = 0\n",
    "max_id = \"\"\n",
    "min = 100\n",
    "min_id = \"\"\n",
    "\n",
    "for user, rate in asr_per_user.items():\n",
    "    if max < rate:\n",
    "        max = rate\n",
    "        max_id = user\n",
    "    if min > rate:\n",
    "        min = rate\n",
    "        min_id = user\n",
    "    print(f\"User {user}: {rate*100:.4f}%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 166,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Max success attack: user 1: 2.75%\n",
      "Min success attack: user 0: 2.5%\n"
     ]
    }
   ],
   "source": [
    "print(f\"Max success attack: user {max_id}: {max*100}%\")\n",
    "print(f\"Min success attack: user {min_id}: {min*100}%\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Attack on: Omni_RI 3bpf, 3seconds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 172,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load the keras model\n",
    "omniRI_3bpf_3sec_model = load_model(\"./3bpf_3sec_inBoundary_1000_auth_6000_Omni_RI.keras\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 173,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Getting users id\n",
    "users_id = []\n",
    "path = \"../users_EKM_files_3sec_3bpf\"\n",
    "dirs = os.listdir(path)\n",
    "for dir in dirs:\n",
    "  user_id = dir.split(\"_\")[-1]\n",
    "  users_id.append(user_id)\n",
    "\n",
    "dataset_path = \"../users_EKM_files_3sec_3bpf\"\n",
    "users_files = os.listdir(dataset_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 176,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Selecting N amount of EKMs for each user\n",
    "users_bpf_EKMs_x = []\n",
    "users_bpf_EKMs_y = []\n",
    "\n",
    "N_each_user_ekms_amount = 400\n",
    "dataset_path = \"../users_EKM_files_3sec_3bpf\"\n",
    "\n",
    "for _files in users_files:\n",
    "    user_id = _files.split(\"_\")[-1]\n",
    "    if user_id in users_id:\n",
    "      for _ekm_number in range(N_each_user_ekms_amount):\n",
    "        # 5bpf-ekm-bpf_recording_signal_length_ekm_dataset-2005-1008.png\n",
    "        users_bpf_EKMs_x.append(f\"{dataset_path}/{user_id}/y_lead/3bpf-ekm-bpf_recording_signal_length_ekm_dataset-{user_id}-{_ekm_number}.png\")\n",
    "        users_bpf_EKMs_y.append(user_id)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 177,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Vectorizing EKMs of users\n",
    "for index, ekm_path in enumerate(users_bpf_EKMs_x):\n",
    "  # progress_bar(index, len(users_bpf_EKMs_x), \"Vertorizing\")\n",
    "  users_bpf_EKMs_x[index] = vertorizing_png_imges(ekm_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 178,
   "metadata": {},
   "outputs": [],
   "source": [
    "label_dict, users_bpf_EKMs_y = numerical_labels(users_bpf_EKMs_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 179,
   "metadata": {},
   "outputs": [],
   "source": [
    "users_bpf_EKMs_x = np.array(users_bpf_EKMs_x)\n",
    "users_bpf_EKMs_y = np.array(users_bpf_EKMs_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 180,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2488/2488 [==============================] - 18s 7ms/step\n"
     ]
    }
   ],
   "source": [
    "y_prob = omniRI_3bpf_3sec_model.predict(users_bpf_EKMs_x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 181,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Attack Success Rate (ASR): 1.9523%\n",
      "\n",
      "Attack Success Rate per User:\n",
      "User 0: 1.2500%\n",
      "User 1: 9.5000%\n",
      "User 2: 0.5000%\n",
      "User 3: 5.2500%\n",
      "User 4: 0.2500%\n",
      "User 5: 1.2500%\n",
      "User 6: 0.5000%\n",
      "User 7: 1.5000%\n",
      "User 8: 0.5000%\n",
      "User 9: 0.2500%\n",
      "User 10: 4.7500%\n",
      "User 11: 0.5000%\n",
      "User 12: 0.2500%\n",
      "User 13: 3.2500%\n",
      "User 14: 12.5000%\n",
      "User 15: 1.0000%\n",
      "User 16: 5.0000%\n",
      "User 17: 0.5000%\n",
      "User 18: 2.0000%\n",
      "User 19: 0.0000%\n",
      "User 20: 1.2500%\n",
      "User 21: 2.0000%\n",
      "User 22: 0.0000%\n",
      "User 23: 4.7500%\n",
      "User 24: 0.0000%\n",
      "User 25: 0.5000%\n",
      "User 26: 0.2500%\n",
      "User 27: 1.0000%\n",
      "User 28: 0.0000%\n",
      "User 29: 0.0000%\n",
      "User 30: 2.0000%\n",
      "User 31: 0.7500%\n",
      "User 32: 4.0000%\n",
      "User 33: 0.7500%\n",
      "User 34: 2.0000%\n",
      "User 35: 2.2500%\n",
      "User 36: 1.0000%\n",
      "User 37: 2.7500%\n",
      "User 38: 3.2500%\n",
      "User 39: 4.5000%\n",
      "User 40: 0.2500%\n",
      "User 41: 0.0000%\n",
      "User 42: 0.7500%\n",
      "User 43: 0.5000%\n",
      "User 44: 0.2500%\n",
      "User 45: 11.5000%\n",
      "User 46: 0.2500%\n",
      "User 47: 0.5000%\n",
      "User 48: 0.7500%\n",
      "User 49: 0.5000%\n",
      "User 50: 2.0000%\n",
      "User 51: 0.2500%\n",
      "User 52: 5.0000%\n",
      "User 53: 15.2500%\n",
      "User 54: 0.2500%\n",
      "User 55: 5.7500%\n",
      "User 56: 0.0000%\n",
      "User 57: 1.7500%\n",
      "User 58: 1.0000%\n",
      "User 59: 0.2500%\n",
      "User 60: 2.2500%\n",
      "User 61: 0.7500%\n",
      "User 62: 0.0000%\n",
      "User 63: 1.7500%\n",
      "User 64: 1.5000%\n",
      "User 65: 1.5000%\n",
      "User 66: 6.7500%\n",
      "User 67: 3.5000%\n",
      "User 68: 2.2500%\n",
      "User 69: 1.2500%\n",
      "User 70: 0.7500%\n",
      "User 71: 0.0000%\n",
      "User 72: 0.7500%\n",
      "User 73: 0.0000%\n",
      "User 74: 0.2500%\n",
      "User 75: 0.0000%\n",
      "User 76: 0.5000%\n",
      "User 77: 0.7500%\n",
      "User 78: 0.2500%\n",
      "User 79: 1.2500%\n",
      "User 80: 3.7500%\n",
      "User 81: 0.2500%\n",
      "User 82: 0.5000%\n",
      "User 83: 2.2500%\n",
      "User 84: 6.5000%\n",
      "User 85: 1.2500%\n",
      "User 86: 0.0000%\n",
      "User 87: 0.5000%\n",
      "User 88: 4.2500%\n",
      "User 89: 3.0000%\n",
      "User 90: 1.2500%\n",
      "User 91: 7.0000%\n",
      "User 92: 3.0000%\n",
      "User 93: 0.2500%\n",
      "User 94: 0.2500%\n",
      "User 95: 5.2500%\n",
      "User 96: 0.5000%\n",
      "User 97: 10.5000%\n",
      "User 98: 7.5000%\n",
      "User 99: 0.2500%\n",
      "User 100: 3.0000%\n",
      "User 101: 0.7500%\n",
      "User 102: 1.0000%\n",
      "User 103: 0.0000%\n",
      "User 104: 0.7500%\n",
      "User 105: 2.2500%\n",
      "User 106: 0.2500%\n",
      "User 107: 4.0000%\n",
      "User 108: 0.7500%\n",
      "User 109: 8.7500%\n",
      "User 110: 2.2500%\n",
      "User 111: 4.0000%\n",
      "User 112: 1.5000%\n",
      "User 113: 0.2500%\n",
      "User 114: 0.7500%\n",
      "User 115: 0.2500%\n",
      "User 116: 1.5000%\n",
      "User 117: 1.0000%\n",
      "User 118: 1.0000%\n",
      "User 119: 4.0000%\n",
      "User 120: 1.7500%\n",
      "User 121: 3.5000%\n",
      "User 122: 1.2500%\n",
      "User 123: 9.2500%\n",
      "User 124: 0.2500%\n",
      "User 125: 3.2500%\n",
      "User 126: 0.0000%\n",
      "User 127: 1.0000%\n",
      "User 128: 2.0000%\n",
      "User 129: 1.5000%\n",
      "User 130: 3.2500%\n",
      "User 131: 0.2500%\n",
      "User 132: 0.0000%\n",
      "User 133: 1.7500%\n",
      "User 134: 2.7500%\n",
      "User 135: 0.0000%\n",
      "User 136: 0.2500%\n",
      "User 137: 0.2500%\n",
      "User 138: 4.5000%\n",
      "User 139: 1.0000%\n",
      "User 140: 0.0000%\n",
      "User 141: 3.2500%\n",
      "User 142: 5.7500%\n",
      "User 143: 3.7500%\n",
      "User 144: 0.2500%\n",
      "User 145: 0.2500%\n",
      "User 146: 3.2500%\n",
      "User 147: 1.5000%\n",
      "User 148: 2.2500%\n",
      "User 149: 0.5000%\n",
      "User 150: 0.5000%\n",
      "User 151: 0.0000%\n",
      "User 152: 2.2500%\n",
      "User 153: 2.7500%\n",
      "User 154: 5.0000%\n",
      "User 155: 1.2500%\n",
      "User 156: 1.0000%\n",
      "User 157: 1.5000%\n",
      "User 158: 1.7500%\n",
      "User 159: 2.5000%\n",
      "User 160: 4.5000%\n",
      "User 161: 10.5000%\n",
      "User 162: 0.5000%\n",
      "User 163: 4.0000%\n",
      "User 164: 0.2500%\n",
      "User 165: 0.0000%\n",
      "User 166: 1.7500%\n",
      "User 167: 2.5000%\n",
      "User 168: 0.2500%\n",
      "User 169: 0.0000%\n",
      "User 170: 5.5000%\n",
      "User 171: 0.0000%\n",
      "User 172: 0.0000%\n",
      "User 173: 0.5000%\n",
      "User 174: 0.0000%\n",
      "User 175: 0.2500%\n",
      "User 176: 0.0000%\n",
      "User 177: 0.7500%\n",
      "User 178: 0.0000%\n",
      "User 179: 0.2500%\n",
      "User 180: 5.5000%\n",
      "User 181: 0.5000%\n",
      "User 182: 0.0000%\n",
      "User 183: 1.5000%\n",
      "User 184: 3.2500%\n",
      "User 185: 0.5000%\n",
      "User 186: 0.5000%\n",
      "User 187: 0.7500%\n",
      "User 188: 0.7500%\n",
      "User 189: 0.2500%\n",
      "User 190: 0.7500%\n",
      "User 191: 2.0000%\n",
      "User 192: 0.0000%\n",
      "User 193: 0.0000%\n",
      "User 194: 2.0000%\n",
      "User 195: 1.7500%\n",
      "User 196: 5.5000%\n",
      "User 197: 0.0000%\n",
      "User 198: 2.2500%\n"
     ]
    }
   ],
   "source": [
    "asr = attack_success_rate(users_bpf_EKMs_y, y_prob.argmax(axis=1))\n",
    "asr_per_user = attack_success_rate_per_user(users_bpf_EKMs_y, y_prob.argmax(axis=1))\n",
    "\n",
    "# Print results\n",
    "print(f\"Attack Success Rate (ASR): {asr*100:.4f}%\")\n",
    "\n",
    "print(\"\\nAttack Success Rate per User:\")\n",
    "max = 0\n",
    "max_id = \"\"\n",
    "min = 100\n",
    "min_id = \"\"\n",
    "\n",
    "for user, rate in asr_per_user.items():\n",
    "    if max < rate:\n",
    "        max = rate\n",
    "        max_id = user\n",
    "    if min > rate:\n",
    "        min = rate\n",
    "        min_id = user\n",
    "    print(f\"User {user}: {rate*100:.4f}%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 182,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Max success attack: user 53: 15.25%\n",
      "Min success attack: user 19: 0.0%\n"
     ]
    }
   ],
   "source": [
    "print(f\"Max success attack: user {max_id}: {max*100}%\")\n",
    "print(f\"Min success attack: user {min_id}: {min*100}%\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Attack on: Mono_RI 3bpf, 3seconds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 183,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load the keras model\n",
    "monoRI_3bpf_3sec_model = load_model(\"./3bpf_3sec_inBoundary_1000_auth_6000_Mono_RI_user1027.keras\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 184,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Getting users id\n",
    "users_id = []\n",
    "path = \"../users_EKM_files_3sec_3bpf\"\n",
    "dirs = os.listdir(path)\n",
    "for dir in dirs:\n",
    "  user_id = dir.split(\"_\")[-1]\n",
    "  users_id.append(user_id)\n",
    "\n",
    "dataset_path = \"../users_EKM_files_3sec_3bpf\"\n",
    "users_files = os.listdir(dataset_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 185,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Creating dict of counters for each randomly-chosen users\n",
    "# of ecg 200 dataset\n",
    "# Also creating dict of users' EKMs\n",
    "ecg_200_users_EKM_amount_dict = {}\n",
    "ecg_200_users_EKMs_dict = {}\n",
    "\n",
    "for user in users_id:\n",
    "  ecg_200_users_EKM_amount_dict[user] = 0\n",
    "  ecg_200_users_EKMs_dict[user] = []"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 186,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Counting each user's EKMs in dataset and collecting EKMs of him/her\n",
    "dataset_path = \"../users_EKM_files_3sec_3bpf\"\n",
    "users_files = os.listdir(dataset_path)\n",
    "\n",
    "for _files in users_files:\n",
    "    user_id = _files.split(\"_\")[-1]\n",
    "    if user_id in users_id:\n",
    "      ecg_200_users_EKM_amount_dict[user_id] = len(os.listdir(f\"{dataset_path}/{user_id}/y_lead\"))\n",
    "      ecg_200_users_EKMs_dict[user_id] = os.listdir(f\"{dataset_path}/{user_id}/y_lead\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 187,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Function to extract the number at the end of the string\n",
    "import re\n",
    "def extract_number(s): \n",
    "  match = re.search(r'-(\\d+)\\.png$', s) \n",
    "  return int(match.group(1)) if match else -1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 188,
   "metadata": {},
   "outputs": [],
   "source": [
    "dataset_path = \"../users_EKM_files_3sec_3bpf\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 189,
   "metadata": {},
   "outputs": [],
   "source": [
    "def one_vs_all_EKMs(user_id):\n",
    "    '''\n",
    "    Gets the id of user and returns the X and y for the model\n",
    "    '''\n",
    "\n",
    "    # Selecting N amount of EKMs for the random user\n",
    "    users_bpf_EKMs_x = []\n",
    "    users_bpf_EKMs_y = []\n",
    "\n",
    "    N_each_user_ekms_amount = 400\n",
    "\n",
    "    if user_id in users_id:\n",
    "        userid_ekms = ecg_200_users_EKMs_dict[user_id][:N_each_user_ekms_amount]\n",
    "        \n",
    "        # Sort the array based on the extracted number \n",
    "        sorted_userid_ekms = sorted(userid_ekms, key=extract_number)\n",
    "        \n",
    "        if len(sorted_userid_ekms) < N_each_user_ekms_amount:\n",
    "            print(user_id, len(sorted_userid_ekms))\n",
    "        \n",
    "        for _ekm in sorted_userid_ekms:\n",
    "            # 5bpf-ekm-bpf_recording_signal_length_ekm_dataset-2005-1008.png\n",
    "            users_bpf_EKMs_x.append(f\"{dataset_path}/{user_id}/y_lead/{_ekm}\")\n",
    "            users_bpf_EKMs_y.append(1)\n",
    "\n",
    "    # Selecting N amount of EKMs for the rest of users\n",
    "    rest_users = [_ for _ in users_files if _ != user_id]\n",
    "    N_rest_user_ekms_amount = 8  # 400 / 199 => 2\n",
    "\n",
    "    for _files in rest_users[:50]:\n",
    "        rest_user_id = _files.split(\"_\")[-1]\n",
    "        if rest_user_id in users_id:\n",
    "            userid_ekms = ecg_200_users_EKMs_dict[rest_user_id][:N_rest_user_ekms_amount]\n",
    "            # Sort the array based on the extracted number \n",
    "            sorted_userid_ekms = sorted(userid_ekms, key=extract_number)\n",
    "            \n",
    "            if len(sorted_userid_ekms) < N_rest_user_ekms_amount:\n",
    "                print(rest_user_id, len(sorted_userid_ekms))\n",
    "            \n",
    "            for _ekm in sorted_userid_ekms:\n",
    "                # 5bpf-ekm-bpf_recording_signal_length_ekm_dataset-2005-1008.png\n",
    "                users_bpf_EKMs_x.append(f\"{dataset_path}/{rest_user_id}/y_lead/{_ekm}\")\n",
    "                users_bpf_EKMs_y.append(0)\n",
    "    \n",
    "    return users_bpf_EKMs_x, users_bpf_EKMs_y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 190,
   "metadata": {},
   "outputs": [],
   "source": [
    "users_bpf_EKMs_x, users_bpf_EKMs_y = one_vs_all_EKMs(\"1027\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 191,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Vectorizing EKMs of users\n",
    "for index, ekm_path in enumerate(users_bpf_EKMs_x):\n",
    "  # progress_bar(index, len(users_bpf_EKMs_x), \"Vertorizing\")\n",
    "  users_bpf_EKMs_x[index] = vertorizing_png_imges(ekm_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 192,
   "metadata": {},
   "outputs": [],
   "source": [
    "users_bpf_EKMs_x = np.array(users_bpf_EKMs_x)\n",
    "users_bpf_EKMs_y = np.array(users_bpf_EKMs_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 193,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "25/25 [==============================] - 0s 8ms/step\n"
     ]
    }
   ],
   "source": [
    "y_prob = monoRI_3bpf_3sec_model.predict(users_bpf_EKMs_x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 194,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Attack Success Rate (ASR): 0.7500%\n",
      "\n",
      "Attack Success Rate per User:\n",
      "User 0: 0.7500%\n",
      "User 1: 0.7500%\n"
     ]
    }
   ],
   "source": [
    "asr = attack_success_rate(users_bpf_EKMs_y, y_prob.argmax(axis=1))\n",
    "asr_per_user = attack_success_rate_per_user(users_bpf_EKMs_y, y_prob.argmax(axis=1))\n",
    "\n",
    "# Print results\n",
    "print(f\"Attack Success Rate (ASR): {asr*100:.4f}%\")\n",
    "\n",
    "print(\"\\nAttack Success Rate per User:\")\n",
    "max = 0\n",
    "max_id = \"\"\n",
    "min = 100\n",
    "min_id = \"\"\n",
    "\n",
    "for user, rate in asr_per_user.items():\n",
    "    if max < rate:\n",
    "        max = rate\n",
    "        max_id = user\n",
    "    if min > rate:\n",
    "        min = rate\n",
    "        min_id = user\n",
    "    print(f\"User {user}: {rate*100:.4f}%\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 195,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Max success attack: user 0: 0.75%\n",
      "Min success attack: user 0: 0.75%\n"
     ]
    }
   ],
   "source": [
    "print(f\"Max success attack: user {max_id}: {max*100}%\")\n",
    "print(f\"Min success attack: user {min_id}: {min*100}%\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Attack on: Omni_RI 3bpf, 4seconds"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 203,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "Error when deserializing class 'InputLayer' using config={'batch_shape': [None, 20, 31, 3], 'dtype': 'float32', 'sparse': False, 'name': 'input_layer'}.\n\nException encountered: Unrecognized keyword arguments: ['batch_shape']",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mValueError\u001b[0m                                Traceback (most recent call last)",
      "File \u001b[0;32m~/Amirhossein/panTompkins/bpf based in boudary EKM alpha 0.2 elements 6000/.venv/lib/python3.8/site-packages/keras/src/engine/base_layer.py:868\u001b[0m, in \u001b[0;36mLayer.from_config\u001b[0;34m(cls, config)\u001b[0m\n\u001b[1;32m    867\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 868\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mcls\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mconfig\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    869\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n",
      "File \u001b[0;32m~/Amirhossein/panTompkins/bpf based in boudary EKM alpha 0.2 elements 6000/.venv/lib/python3.8/site-packages/keras/src/utils/traceback_utils.py:70\u001b[0m, in \u001b[0;36mfilter_traceback.<locals>.error_handler\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m     68\u001b[0m     \u001b[38;5;66;03m# To get the full stack trace, call:\u001b[39;00m\n\u001b[1;32m     69\u001b[0m     \u001b[38;5;66;03m# `tf.debugging.disable_traceback_filtering()`\u001b[39;00m\n\u001b[0;32m---> 70\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m e\u001b[38;5;241m.\u001b[39mwith_traceback(filtered_tb) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[1;32m     71\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n",
      "File \u001b[0;32m~/Amirhossein/panTompkins/bpf based in boudary EKM alpha 0.2 elements 6000/.venv/lib/python3.8/site-packages/keras/src/engine/input_layer.py:153\u001b[0m, in \u001b[0;36mInputLayer.__init__\u001b[0;34m(self, input_shape, batch_size, dtype, input_tensor, sparse, name, ragged, type_spec, **kwargs)\u001b[0m\n\u001b[1;32m    152\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m kwargs:\n\u001b[0;32m--> 153\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m    154\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mUnrecognized keyword arguments: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mlist\u001b[39m(kwargs\u001b[38;5;241m.\u001b[39mkeys())\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m    155\u001b[0m     )\n\u001b[1;32m    157\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m sparse \u001b[38;5;129;01mand\u001b[39;00m ragged:\n",
      "\u001b[0;31mValueError\u001b[0m: Unrecognized keyword arguments: ['batch_shape']",
      "\nDuring handling of the above exception, another exception occurred:\n",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "Cell \u001b[0;32mIn[203], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m omniRI_3bpf_4sec_model \u001b[38;5;241m=\u001b[39m \u001b[43mload_model\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43m./3bpf_4sec_inBoundary_1000_auth_6000_Omni_RI.keras\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/Amirhossein/panTompkins/bpf based in boudary EKM alpha 0.2 elements 6000/.venv/lib/python3.8/site-packages/keras/src/saving/saving_api.py:230\u001b[0m, in \u001b[0;36mload_model\u001b[0;34m(filepath, custom_objects, compile, safe_mode, **kwargs)\u001b[0m\n\u001b[1;32m    225\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m kwargs:\n\u001b[1;32m    226\u001b[0m         \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m    227\u001b[0m             \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mThe following argument(s) are not supported \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m    228\u001b[0m             \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mwith the native Keras format: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mlist\u001b[39m(kwargs\u001b[38;5;241m.\u001b[39mkeys())\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m    229\u001b[0m         )\n\u001b[0;32m--> 230\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43msaving_lib\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload_model\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    231\u001b[0m \u001b[43m        \u001b[49m\u001b[43mfilepath\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    232\u001b[0m \u001b[43m        \u001b[49m\u001b[43mcustom_objects\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcustom_objects\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    233\u001b[0m \u001b[43m        \u001b[49m\u001b[38;5;28;43mcompile\u001b[39;49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mcompile\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m    234\u001b[0m \u001b[43m        \u001b[49m\u001b[43msafe_mode\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msafe_mode\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    235\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    237\u001b[0m \u001b[38;5;66;03m# Legacy case.\u001b[39;00m\n\u001b[1;32m    238\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m legacy_sm_saving_lib\u001b[38;5;241m.\u001b[39mload_model(\n\u001b[1;32m    239\u001b[0m     filepath, custom_objects\u001b[38;5;241m=\u001b[39mcustom_objects, \u001b[38;5;28mcompile\u001b[39m\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mcompile\u001b[39m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs\n\u001b[1;32m    240\u001b[0m )\n",
      "File \u001b[0;32m~/Amirhossein/panTompkins/bpf based in boudary EKM alpha 0.2 elements 6000/.venv/lib/python3.8/site-packages/keras/src/saving/saving_lib.py:275\u001b[0m, in \u001b[0;36mload_model\u001b[0;34m(filepath, custom_objects, compile, safe_mode)\u001b[0m\n\u001b[1;32m    272\u001b[0m             asset_store\u001b[38;5;241m.\u001b[39mclose()\n\u001b[1;32m    274\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m--> 275\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m e\n\u001b[1;32m    276\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m    277\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m model\n",
      "File \u001b[0;32m~/Amirhossein/panTompkins/bpf based in boudary EKM alpha 0.2 elements 6000/.venv/lib/python3.8/site-packages/keras/src/saving/saving_lib.py:240\u001b[0m, in \u001b[0;36mload_model\u001b[0;34m(filepath, custom_objects, compile, safe_mode)\u001b[0m\n\u001b[1;32m    238\u001b[0m \u001b[38;5;66;03m# Construct the model from the configuration file in the archive.\u001b[39;00m\n\u001b[1;32m    239\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m ObjectSharingScope():\n\u001b[0;32m--> 240\u001b[0m     model \u001b[38;5;241m=\u001b[39m \u001b[43mdeserialize_keras_object\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    241\u001b[0m \u001b[43m        \u001b[49m\u001b[43mconfig_dict\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcustom_objects\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msafe_mode\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msafe_mode\u001b[49m\n\u001b[1;32m    242\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    244\u001b[0m all_filenames \u001b[38;5;241m=\u001b[39m zf\u001b[38;5;241m.\u001b[39mnamelist()\n\u001b[1;32m    245\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m _VARS_FNAME \u001b[38;5;241m+\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m.h5\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m all_filenames:\n",
      "File \u001b[0;32m~/Amirhossein/panTompkins/bpf based in boudary EKM alpha 0.2 elements 6000/.venv/lib/python3.8/site-packages/keras/src/saving/serialization_lib.py:704\u001b[0m, in \u001b[0;36mdeserialize_keras_object\u001b[0;34m(config, custom_objects, safe_mode, **kwargs)\u001b[0m\n\u001b[1;32m    702\u001b[0m safe_mode_scope \u001b[38;5;241m=\u001b[39m SafeModeScope(safe_mode)\n\u001b[1;32m    703\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m custom_obj_scope, safe_mode_scope:\n\u001b[0;32m--> 704\u001b[0m     instance \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mcls\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfrom_config\u001b[49m\u001b[43m(\u001b[49m\u001b[43minner_config\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    705\u001b[0m     build_config \u001b[38;5;241m=\u001b[39m config\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mbuild_config\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[1;32m    706\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m build_config:\n",
      "File \u001b[0;32m~/Amirhossein/panTompkins/bpf based in boudary EKM alpha 0.2 elements 6000/.venv/lib/python3.8/site-packages/keras/src/engine/sequential.py:473\u001b[0m, in \u001b[0;36mSequential.from_config\u001b[0;34m(cls, config, custom_objects)\u001b[0m\n\u001b[1;32m    471\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m layer_config \u001b[38;5;129;01min\u001b[39;00m layer_configs:\n\u001b[1;32m    472\u001b[0m     use_legacy_format \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmodule\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;129;01min\u001b[39;00m layer_config\n\u001b[0;32m--> 473\u001b[0m     layer \u001b[38;5;241m=\u001b[39m \u001b[43mlayer_module\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdeserialize\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    474\u001b[0m \u001b[43m        \u001b[49m\u001b[43mlayer_config\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    475\u001b[0m \u001b[43m        \u001b[49m\u001b[43mcustom_objects\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcustom_objects\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    476\u001b[0m \u001b[43m        \u001b[49m\u001b[43muse_legacy_format\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43muse_legacy_format\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    477\u001b[0m \u001b[43m    \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    478\u001b[0m     model\u001b[38;5;241m.\u001b[39madd(layer)\n\u001b[1;32m    480\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (\n\u001b[1;32m    481\u001b[0m     \u001b[38;5;129;01mnot\u001b[39;00m model\u001b[38;5;241m.\u001b[39minputs\n\u001b[1;32m    482\u001b[0m     \u001b[38;5;129;01mand\u001b[39;00m build_input_shape\n\u001b[1;32m    483\u001b[0m     \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(build_input_shape, (\u001b[38;5;28mtuple\u001b[39m, \u001b[38;5;28mlist\u001b[39m))\n\u001b[1;32m    484\u001b[0m ):\n",
      "File \u001b[0;32m~/Amirhossein/panTompkins/bpf based in boudary EKM alpha 0.2 elements 6000/.venv/lib/python3.8/site-packages/keras/src/layers/serialization.py:276\u001b[0m, in \u001b[0;36mdeserialize\u001b[0;34m(config, custom_objects, use_legacy_format)\u001b[0m\n\u001b[1;32m    268\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m use_legacy_format:\n\u001b[1;32m    269\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m legacy_serialization\u001b[38;5;241m.\u001b[39mdeserialize_keras_object(\n\u001b[1;32m    270\u001b[0m         config,\n\u001b[1;32m    271\u001b[0m         module_objects\u001b[38;5;241m=\u001b[39mLOCAL\u001b[38;5;241m.\u001b[39mALL_OBJECTS,\n\u001b[1;32m    272\u001b[0m         custom_objects\u001b[38;5;241m=\u001b[39mcustom_objects,\n\u001b[1;32m    273\u001b[0m         printable_module_name\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mlayer\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m    274\u001b[0m     )\n\u001b[0;32m--> 276\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mserialization_lib\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdeserialize_keras_object\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    277\u001b[0m \u001b[43m    \u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    278\u001b[0m \u001b[43m    \u001b[49m\u001b[43mmodule_objects\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mLOCAL\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mALL_OBJECTS\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    279\u001b[0m \u001b[43m    \u001b[49m\u001b[43mcustom_objects\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcustom_objects\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    280\u001b[0m \u001b[43m    \u001b[49m\u001b[43mprintable_module_name\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mlayer\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m    281\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n",
      "File \u001b[0;32m~/Amirhossein/panTompkins/bpf based in boudary EKM alpha 0.2 elements 6000/.venv/lib/python3.8/site-packages/keras/src/saving/serialization_lib.py:600\u001b[0m, in \u001b[0;36mdeserialize_keras_object\u001b[0;34m(config, custom_objects, safe_mode, **kwargs)\u001b[0m\n\u001b[1;32m    593\u001b[0m         \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(module_objects[config], types\u001b[38;5;241m.\u001b[39mFunctionType):\n\u001b[1;32m    594\u001b[0m             \u001b[38;5;28;01mreturn\u001b[39;00m deserialize_keras_object(\n\u001b[1;32m    595\u001b[0m                 serialize_with_public_fn(\n\u001b[1;32m    596\u001b[0m                     module_objects[config], config, fn_module_name\n\u001b[1;32m    597\u001b[0m                 ),\n\u001b[1;32m    598\u001b[0m                 custom_objects\u001b[38;5;241m=\u001b[39mcustom_objects,\n\u001b[1;32m    599\u001b[0m             )\n\u001b[0;32m--> 600\u001b[0m         \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mdeserialize_keras_object\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    601\u001b[0m \u001b[43m            \u001b[49m\u001b[43mserialize_with_public_class\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m    602\u001b[0m \u001b[43m                \u001b[49m\u001b[43mmodule_objects\u001b[49m\u001b[43m[\u001b[49m\u001b[43mconfig\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43minner_config\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43minner_config\u001b[49m\n\u001b[1;32m    603\u001b[0m \u001b[43m            \u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    604\u001b[0m \u001b[43m            \u001b[49m\u001b[43mcustom_objects\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcustom_objects\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m    605\u001b[0m \u001b[43m        \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    607\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(config, PLAIN_TYPES):\n\u001b[1;32m    608\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m config\n",
      "File \u001b[0;32m~/Amirhossein/panTompkins/bpf based in boudary EKM alpha 0.2 elements 6000/.venv/lib/python3.8/site-packages/keras/src/saving/serialization_lib.py:704\u001b[0m, in \u001b[0;36mdeserialize_keras_object\u001b[0;34m(config, custom_objects, safe_mode, **kwargs)\u001b[0m\n\u001b[1;32m    702\u001b[0m safe_mode_scope \u001b[38;5;241m=\u001b[39m SafeModeScope(safe_mode)\n\u001b[1;32m    703\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m custom_obj_scope, safe_mode_scope:\n\u001b[0;32m--> 704\u001b[0m     instance \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mcls\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfrom_config\u001b[49m\u001b[43m(\u001b[49m\u001b[43minner_config\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m    705\u001b[0m     build_config \u001b[38;5;241m=\u001b[39m config\u001b[38;5;241m.\u001b[39mget(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mbuild_config\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;28;01mNone\u001b[39;00m)\n\u001b[1;32m    706\u001b[0m     \u001b[38;5;28;01mif\u001b[39;00m build_config:\n",
      "File \u001b[0;32m~/Amirhossein/panTompkins/bpf based in boudary EKM alpha 0.2 elements 6000/.venv/lib/python3.8/site-packages/keras/src/engine/base_layer.py:870\u001b[0m, in \u001b[0;36mLayer.from_config\u001b[0;34m(cls, config)\u001b[0m\n\u001b[1;32m    868\u001b[0m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mcls\u001b[39m(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mconfig)\n\u001b[1;32m    869\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m--> 870\u001b[0m     \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m(\n\u001b[1;32m    871\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mError when deserializing class \u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;132;01m{\u001b[39;00m\u001b[38;5;28mcls\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__name__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124m using \u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m    872\u001b[0m         \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mconfig=\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mconfig\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m.\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;124mException encountered: \u001b[39m\u001b[38;5;132;01m{\u001b[39;00me\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m    873\u001b[0m     )\n",
      "\u001b[0;31mTypeError\u001b[0m: Error when deserializing class 'InputLayer' using config={'batch_shape': [None, 20, 31, 3], 'dtype': 'float32', 'sparse': False, 'name': 'input_layer'}.\n\nException encountered: Unrecognized keyword arguments: ['batch_shape']"
     ]
    }
   ],
   "source": [
    "omniRI_3bpf_4sec_model = load_model(\"./3bpf_4sec_inBoundary_1000_auth_6000_Omni_RI.keras\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
